package com.xz.xzmybatisagent;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

public class MyJsonUtil {
    private MyJsonUtil() {
    }

    public static String convertMapToJson(Map<String, Object> map) {
        try {
            return new MyJsonUtil().convertMapToJsonInternal(map);
        } catch (Throwable t) {
            System.err.println("Map object can not parse to JSON: " + t.getMessage());
        }
        return "{}";
    }

    public static String convertObjectToJson(Object object) {
        try {
            MyJsonUtil mapToJson = new MyJsonUtil();
            if (object == null) {
                return mapToJson.convertNull();
            } else if (object instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> map = (Map<String, Object>) object;
                return mapToJson.convertMapToJsonInternal(map);
            } else {
                return mapToJson.convertObject(object);
            }
        } catch (Throwable t) {
            System.err.println("Object can not parse to JSON: " + t.getMessage());
        }
        return "{}";
    }

    private String convertMapToJsonInternal(Map<String, Object> map) {
        StringBuilder jsonBuilder = new StringBuilder("{");
        boolean first = true;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!first) {
                jsonBuilder.append(",");
            } else {
                first = false;
            }
            jsonBuilder.append("\"").append(entry.getKey()).append("\":");
            jsonBuilder.append(convertValueToJson(entry.getValue()));
        }
        jsonBuilder.append("}");
        return jsonBuilder.toString();
    }

    private String convertValueToJson(Object value) {
        if (value == null) {
            return convertNull();
        } else if (value instanceof String) {
            return convertString((String) value);
        } else if (value instanceof Number) {
            return convertNumber((Number) value);
        } else if (value instanceof Boolean) {
            return convertBoolean((Boolean) value);
        } else if (value instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (Map<String, Object>) value;
            return convertMapToJsonInternal(map);
        } else if (value instanceof List) {
            @SuppressWarnings("unchecked")
            List<Object> list = (List<Object>) value;
            return convertList(list);
        } else {
            return convertObject(value);
        }
    }

    private String convertBoolean(Boolean value) {
        return Boolean.toString(value);
    }

    private String convertNumber(Number value) {
        return value.toString();
    }

    private String convertString(String value) {
        StringBuilder sb = new StringBuilder(value.length() + 2).append("\"");
        for (char c : value.toCharArray()) {
            switch (c) {
                case '\\':
                    sb.append("\\\\");
                    break;
                case '\"':
                    sb.append("\\\"");
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\r':
                    sb.append("\\r");
                    break;
                case '\t':
                    sb.append("\\t");
                    break;
                case '\b':
                    sb.append("\\b");
                    break;
                case '\f':
                    sb.append("\\f");
                    break;
                default:
                    if (c < 0x20) { // 处理控制字符
                        sb.append(String.format("\\u%04x", (int) c));
                    } else {
                        sb.append(c);
                    }
            }
        }
        return sb.append("\"").toString();
    }

    private String convertNull() {
        return "null";
    }

    private String convertList(List<?> list) {
        StringBuilder jsonBuilder = new StringBuilder("[");
        boolean first = true;
        for (Object value : list) {
            if (!first) {
                jsonBuilder.append(",");
            } else {
                first = false;
            }
            jsonBuilder.append(convertValueToJson(value));
        }
        jsonBuilder.append("]");
        return jsonBuilder.toString();
    }

    private String convertObject(Object object) {
        StringBuilder jsonBuilder = new StringBuilder("{");
        boolean first = true;
        for (Field field : object.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            try {
                Object value = field.get(object);
                if (!first) {
                    jsonBuilder.append(",");
                } else {
                    first = false;
                }
                jsonBuilder.append("\"").append(field.getName()).append("\":");
                jsonBuilder.append(convertValueToJson(value));
            } catch (IllegalAccessException e) {
                System.out.println("Unable to convert object to JSON" + e.getMessage());
            }
        }
        jsonBuilder.append("}");
        return jsonBuilder.toString();
    }

    // TODO
    // 读取配置文件
    // properties1 = value1
    // properties2 = value2
    private static String readTxtFile(String filePath) {
        StringBuilder content = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line).append("\n");
            }
        } catch (IOException e) {
            //
        }
        return content.toString();
    }
}